package org.jeecg.modules.tranEventScan;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.biz.entity.EventBet;
import org.jeecg.modules.biz.entity.EventSettle;
import org.jeecg.modules.biz.service.EventBetService;
import org.jeecg.modules.biz.service.EventSettleService;
import org.jeecg.modules.utils.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * 认筹事件任务扫描
 *
 */
@Slf4j
@Component
@EnableScheduling
public class Settle {
    // host
    @Value("${tronEvent.host}")
    private String TRON_EVENT_HOST;
    // 合约地址
    @Value("${tronEvent.contractsAddress.settle}")
    private String CONTRACTS_Address;
    // 认筹事件名
    @Value("${tronEvent.eventName.settle}")
    private String EVENT_NAME;
    // 每页数量
    @Value("${tronEvent.page_size}")
    private String PAGE_SIZE;

    private final String method = "GET";
    private Map<String, String> headers = new HashMap<>();

    @Autowired
    private EventSettleService settleService;

    // 认筹事件扫描
    @Scheduled(cron = "0 */1 * * * ?")
    @Transactional
    public void eventBetScan(){
        try {
            EventSettle currentEventSettle = settleService.getLatestOne();

            String host = TRON_EVENT_HOST + "/" + CONTRACTS_Address + "/events";
            Map<String, String> query = new HashMap<String, String>();
            query.put("limit", PAGE_SIZE);
            query.put("event_name", EVENT_NAME);
            String transactionId = currentEventSettle == null ? "" : currentEventSettle.getTransactionId();

            eventBetRequest(host, query, transactionId);
        } catch (Exception e) {
            if(!(e instanceof JeecgBootException)){
                log.info(e.getMessage());
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }
    }

    // 认筹事件发送http请求
    private void eventBetRequest(String host, Map<String, String> query, String transactionId){
        JSONObject jsonObject = null;
        try {
            HttpResponse httpResponse = HttpUtils.doGet(host, "", method, headers, query);
            jsonObject = JSONObject.parseObject(EntityUtils.toString(httpResponse.getEntity()));
        } catch (Exception e) {
            throw new JeecgBootException(e.getMessage());
        }

        if(jsonObject != null){
            eventSettleInsert((JSONArray)jsonObject.get("data"), transactionId);
        }

        // ((JSONObject)((JSONObject)jsonObject.get("meta")).get("links")).get("next");
        JSONObject links = (JSONObject) ((JSONObject)jsonObject.get("meta")).get("links");
        if(links != null){
            String nextHost = (String) links.get("next");
            eventBetRequest(nextHost, new HashMap<String, String>(), transactionId);
        }
    }

    // 认筹事件入库
    private void eventSettleInsert(JSONArray responseDataArray, String currentTransactionId){
        for(Object responseData : responseDataArray){
            String transactionId = (String) ((JSONObject) responseData).get("transaction_id");
            if(transactionId.equals(currentTransactionId)){
                throw new JeecgBootException("本轮添加完成");
            }

            Long blockTimestamp = (Long) ((JSONObject) responseData).get("block_timestamp");

            Object result = ((JSONObject) responseData).get("result");
            String caller = "41" + String.valueOf(((JSONObject) result).get("from")).substring(2);
            String inviter = "41" + String.valueOf(((JSONObject) result).get("inviter")).substring(2);
            Long profit = Long.valueOf(String.valueOf(((JSONObject) result).get("tokenAmount")));
            String dateStr = String.valueOf(((JSONObject) result).get("date"));
            Date date = new Date(blockTimestamp);
            Timestamp timestamp = new Timestamp(blockTimestamp);

            EventSettle eventSettle = new EventSettle(caller, inviter, profit, transactionId, date, timestamp);
            try {
                settleService.saveAndUpdateEventBet(eventSettle, dateStr);
            } catch (Exception e) {
                if(!(e instanceof DuplicateKeyException)){
                    throw e;
                }
            }
        }
    }
}
